package edu.vt.ece.rt.benchmark.labyrinth;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import edu.vt.ece.rt.benchmark.hashmap.Hashmap;

public class Grid {
    long width;
    long height;
    long depth;
    HashMap<String,Coordinate> points;
    ArrayList<Long> points_unaligned;
    
    public static long GRID_POINT_FULL = -2L;
    public static long GRID_POINT_EMPTY = -1L;
    
    
    public Grid(long height, long width, long depth) {
    	this.height = height;
    	this.width = width;
    	this.depth = depth;
    	points = new HashMap<String,Coordinate>();
    	points_unaligned = new ArrayList<Long>();
    
    	for (long h = 0 ; h < height ; h++) {
    		for (long w = 0; w < width; w++) {
    			for (long d =0; d < depth; d++) {
    				String id = h+"-"+w+"-"+d;
    				Coordinate c = new Coordinate(h,w,d);
    				c.value = Grid.GRID_POINT_EMPTY;
    				points.put(id, c);
    			}
    		}
    	}
    
    }
    
    public Grid(Grid g) {
    	this.height = g.height;
    	this.width = g.width;
    	this.depth = g.depth;
    	points = new HashMap<String,Coordinate>();
    	points_unaligned = new ArrayList<Long>();
    
    	for (Entry<String,Coordinate> e : g.points.entrySet()) {
    		String key = e.getKey();
    		Coordinate oldC = e.getValue();
    		Coordinate newC = new Coordinate(oldC.x, oldC.y, oldC.z);
    		newC.value = oldC.value;
    		points.put(key, newC);
    	}
    }
    

    /* =============================================================================
     * grid_isPointValid
     * =============================================================================
     */
    static boolean
    grid_isPointValid (Grid gridPtr, long x, long y, long z)
    {
        if (x < 0 || x >= gridPtr.width  ||
            y < 0 || y >= gridPtr.height ||
            z < 0 || z >= gridPtr.depth)
        {
            return false;
        }

        return true;
    }

    /* =============================================================================
     * addToGrid
     * =============================================================================
     */
    static void
    addToGrid (Grid gridPtr, ArrayList<Coordinate> vectorPtr, String type)
    {
        for (Coordinate coordinatePtr : vectorPtr) {
            if (!grid_isPointValid(gridPtr,
                                   coordinatePtr.x,
                                   coordinatePtr.y,
                                   coordinatePtr.z))
            {
            	return;
            }
        }
        Grid.grid_addPath(gridPtr, vectorPtr);
    }

    /* =============================================================================
     * grid_addPath
     * =============================================================================
     */
    static void
    grid_addPath (Grid gridPtr, ArrayList<Coordinate> pointVectorPtr)
    {
    	for (Coordinate coordinatePtr : pointVectorPtr) {
            long x = coordinatePtr.x;
            long y = coordinatePtr.y;
            long z = coordinatePtr.z;
            grid_setPoint(gridPtr, x, y, z, Grid.GRID_POINT_FULL);
        }
    }
    
    static void grid_setPoint(Grid gridPtr, long x, long y, long z, long value) {
    	String id = x+"-"+y+"-"+z;
    	Coordinate coordinate = gridPtr.points.get(id);
    	coordinate.value = value;    	
    }

    static Coordinate grid_getPoint(Grid gridPtr, Coordinate coor) {
    	long x = coor.x;
    	long y = coor.y;
    	long z = coor.z;
    	String id = x+"-"+y+"-"+z;
    	Coordinate coordinate = gridPtr.points.get(id);
    	return coordinate;
    }

    static Coordinate grid_getPoint(Grid gridPtr, long x, long y, long z) {
    	String id = x+"-"+y+"-"+z;
    	Coordinate coordinate = gridPtr.points.get(id);
    	return coordinate;
    }

    static boolean 
    grid_isPointEmpty(Grid gridPtr, long x, long y, long z) {
    	String id = x+"-"+y+"-"+z;
    	Coordinate coordinate = gridPtr.points.get(id);
    	long value = coordinate.value;
    	if (value == Grid.GRID_POINT_EMPTY)
    		return true;
    	else 
    		return false;
    	
    }

    static boolean 
    grid_isPointFull(Grid gridPtr, long x, long y, long z) {
    	String id = x+"-"+y+"-"+z;
    	Coordinate coordinate = gridPtr.points.get(id);
    	long value = coordinate.value;
    	if (value == Grid.GRID_POINT_FULL)
    		return true;
    	else 
    		return false;
    	
    }

}
